package handler

import (
	"net/http"
	"strconv"
	"time"

	"rdiot-demo/internal/eav/domain"
	"rdiot-demo/internal/eav/eav_service"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
)

// API API控制器集合
type API struct {
	TemplateAPI TemplateAPI
	EntityAPI   EntityAPI
	logger      *zap.Logger
}

// TemplateAPI 模板API接口
type TemplateAPI interface {
	CreateTemplate(c *gin.Context)
	GetTemplate(c *gin.Context)
	UpdateTemplate(c *gin.Context)
	DeleteTemplate(c *gin.Context)
	ListTemplates(c *gin.Context)
}

// EntityAPI 实体API接口
type EntityAPI interface {
	CreateEntity(c *gin.Context)
	GetEntity(c *gin.Context)
	UpdateEntity(c *gin.Context)
	DeleteEntity(c *gin.Context)
	QueryEntities(c *gin.Context)
	GetEntityWithAttributes(c *gin.Context)
	BatchCreateEntities(c *gin.Context)
	GetEntitiesByTemplate(c *gin.Context)
}

// templateHandler 模板API处理器
type templateHandler struct {
	templateService eav_service.TemplateService
	logger          *zap.Logger
}

// entityHandler 实体API处理器
type entityHandler struct {
	entityService eav_service.EntityService
	logger        *zap.Logger
}

// APIResponse 统一API响应格式
type APIResponse struct {
	Code      int         `json:"code"`
	Message   string      `json:"message"`
	Data      interface{} `json:"data,omitempty"`
	Timestamp time.Time   `json:"timestamp"`
}

// PaginatedResponse 分页响应
type PaginatedResponse struct {
	Items      interface{} `json:"items"`
	TotalCount int64       `json:"total_count"`
	Page       int         `json:"page"`
	Size       int         `json:"size"`
	TotalPages int         `json:"total_pages"`
}

// NewAPI 创建API实例
func NewAPI(services *eav_service.EAVServices, logger *zap.Logger) *API {
	return &API{
		TemplateAPI: &templateHandler{
			templateService: services.TemplateService,
			logger:          logger,
		},
		EntityAPI: &entityHandler{
			entityService: services.EntityService,
			logger:        logger,
		},
		logger: logger,
	}
}

// =============== 模板API实现 ===============

// CreateTemplate 创建模板
func (h *templateHandler) CreateTemplate(c *gin.Context) {
	var req domain.EntityTemplate

	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	// 设置ID和时间戳
	req.ID = uuid.New()
	req.CreatedAt = time.Now()
	req.UpdatedAt = time.Now()

	if err := h.templateService.CreateTemplate(c.Request.Context(), &req); err != nil {
		h.logger.Error("Failed to create template", zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to create template: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusCreated, APIResponse{
		Code:      http.StatusCreated,
		Message:   "Template created successfully",
		Data:      req,
		Timestamp: time.Now(),
	})
}

// GetTemplate 获取模板
func (h *templateHandler) GetTemplate(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid template ID format",
			Timestamp: time.Now(),
		})
		return
	}

	template, err := h.templateService.GetTemplate(c.Request.Context(), id)
	if err != nil {
		h.logger.Error("Failed to get template", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusNotFound, APIResponse{
			Code:      http.StatusNotFound,
			Message:   "Template not found: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Template retrieved successfully",
		Data:      template,
		Timestamp: time.Now(),
	})
}

// UpdateTemplate 更新模板
func (h *templateHandler) UpdateTemplate(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid template ID format",
			Timestamp: time.Now(),
		})
		return
	}

	var req domain.EntityTemplate
	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	// 确保ID一致并更新时间戳
	req.ID = id
	req.UpdatedAt = time.Now()

	if err := h.templateService.UpdateTemplate(c.Request.Context(), &req); err != nil {
		h.logger.Error("Failed to update template", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to update template: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Template updated successfully",
		Data:      req,
		Timestamp: time.Now(),
	})
}

// DeleteTemplate 删除模板
func (h *templateHandler) DeleteTemplate(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid template ID format",
			Timestamp: time.Now(),
		})
		return
	}

	if err := h.templateService.DeleteTemplate(c.Request.Context(), id); err != nil {
		h.logger.Error("Failed to delete template", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to delete template: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Template deleted successfully",
		Timestamp: time.Now(),
	})
}

// ListTemplates 列出模板
func (h *templateHandler) ListTemplates(c *gin.Context) {
	// 解析查询参数
	filter := eav_service.TemplateFilter{
		Name: c.Query("name"),
		Page: 1,
		Size: 10,
	}

	if pageStr := c.Query("page"); pageStr != "" {
		if page, err := strconv.Atoi(pageStr); err == nil && page > 0 {
			filter.Page = page
		}
	}

	if sizeStr := c.Query("size"); sizeStr != "" {
		if size, err := strconv.Atoi(sizeStr); err == nil && size > 0 && size <= 100 {
			filter.Size = size
		}
	}

	if isActiveStr := c.Query("is_active"); isActiveStr != "" {
		if isActive, err := strconv.ParseBool(isActiveStr); err == nil {
			filter.IsActive = &isActive
		}
	}

	templates, total, err := h.templateService.ListTemplates(c.Request.Context(), filter)
	if err != nil {
		h.logger.Error("Failed to list templates", zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to list templates: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	totalPages := int((total + int64(filter.Size) - 1) / int64(filter.Size))

	c.JSON(http.StatusOK, APIResponse{
		Code:    http.StatusOK,
		Message: "Templates retrieved successfully",
		Data: PaginatedResponse{
			Items:      templates,
			TotalCount: total,
			Page:       filter.Page,
			Size:       filter.Size,
			TotalPages: totalPages,
		},
		Timestamp: time.Now(),
	})
}

// =============== 实体API实现 ===============

// CreateEntity 创建实体
func (h *entityHandler) CreateEntity(c *gin.Context) {
	var req eav_service.CreateEntityRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	entity, err := h.entityService.CreateEntity(c.Request.Context(), req)
	if err != nil {
		h.logger.Error("Failed to create entity", zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to create entity: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusCreated, APIResponse{
		Code:      http.StatusCreated,
		Message:   "Entity created successfully",
		Data:      entity,
		Timestamp: time.Now(),
	})
}

// GetEntity 获取实体
func (h *entityHandler) GetEntity(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid entity ID format",
			Timestamp: time.Now(),
		})
		return
	}

	entity, err := h.entityService.GetEntityByID(c.Request.Context(), id)
	if err != nil {
		h.logger.Error("Failed to get entity", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusNotFound, APIResponse{
			Code:      http.StatusNotFound,
			Message:   "Entity not found: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Entity retrieved successfully",
		Data:      entity,
		Timestamp: time.Now(),
	})
}

// UpdateEntity 更新实体
func (h *entityHandler) UpdateEntity(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid entity ID format",
			Timestamp: time.Now(),
		})
		return
	}

	var req eav_service.UpdateEntityRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	entity, err := h.entityService.UpdateEntity(c.Request.Context(), id, req)
	if err != nil {
		h.logger.Error("Failed to update entity", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to update entity: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Entity updated successfully",
		Data:      entity,
		Timestamp: time.Now(),
	})
}

// DeleteEntity 删除实体
func (h *entityHandler) DeleteEntity(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid entity ID format",
			Timestamp: time.Now(),
		})
		return
	}

	if err := h.entityService.DeleteEntity(c.Request.Context(), id); err != nil {
		h.logger.Error("Failed to delete entity", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to delete entity: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Entity deleted successfully",
		Timestamp: time.Now(),
	})
}

// QueryEntities 查询实体
func (h *entityHandler) QueryEntities(c *gin.Context) {
	var req eav_service.QueryEntitiesRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	// 设置默认分页参数
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.Size <= 0 {
		req.Size = 10
	}
	if req.Size > 100 {
		req.Size = 100
	}

	entities, total, err := h.entityService.QueryEntities(c.Request.Context(), req)
	if err != nil {
		h.logger.Error("Failed to query entities", zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to query entities: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	totalPages := int((total + int64(req.Size) - 1) / int64(req.Size))

	c.JSON(http.StatusOK, APIResponse{
		Code:    http.StatusOK,
		Message: "Entities queried successfully",
		Data: PaginatedResponse{
			Items:      entities,
			TotalCount: total,
			Page:       req.Page,
			Size:       req.Size,
			TotalPages: totalPages,
		},
		Timestamp: time.Now(),
	})
}

// GetEntityWithAttributes 获取实体及其属性
func (h *entityHandler) GetEntityWithAttributes(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid entity ID format",
			Timestamp: time.Now(),
		})
		return
	}

	entityWithAttrs, err := h.entityService.GetEntityWithAttributes(c.Request.Context(), id)
	if err != nil {
		h.logger.Error("Failed to get entity with attributes", zap.String("id", id.String()), zap.Error(err))
		c.JSON(http.StatusNotFound, APIResponse{
			Code:      http.StatusNotFound,
			Message:   "Entity not found: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusOK, APIResponse{
		Code:      http.StatusOK,
		Message:   "Entity with attributes retrieved successfully",
		Data:      entityWithAttrs,
		Timestamp: time.Now(),
	})
}

// BatchCreateEntities 批量创建实体
func (h *entityHandler) BatchCreateEntities(c *gin.Context) {
	var req eav_service.BatchCreateEntitiesRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Invalid request body", zap.Error(err))
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid request body: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	entities, err := h.entityService.BatchCreateEntities(c.Request.Context(), req)
	if err != nil {
		h.logger.Error("Failed to batch create entities", zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to batch create entities: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	c.JSON(http.StatusCreated, APIResponse{
		Code:      http.StatusCreated,
		Message:   "Entities created successfully",
		Data:      entities,
		Timestamp: time.Now(),
	})
}

// GetEntitiesByTemplate 根据模板获取实体列表
func (h *entityHandler) GetEntitiesByTemplate(c *gin.Context) {
	templateIDStr := c.Param("templateId")
	templateID, err := uuid.Parse(templateIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{
			Code:      http.StatusBadRequest,
			Message:   "Invalid template ID format",
			Timestamp: time.Now(),
		})
		return
	}

	// 解析分页参数
	page := 1
	size := 10

	if pageStr := c.Query("page"); pageStr != "" {
		if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
			page = p
		}
	}

	if sizeStr := c.Query("size"); sizeStr != "" {
		if s, err := strconv.Atoi(sizeStr); err == nil && s > 0 && s <= 100 {
			size = s
		}
	}

	entities, total, err := h.entityService.GetEntitiesByTemplate(c.Request.Context(), templateID, page, size)
	if err != nil {
		h.logger.Error("Failed to get entities by template", zap.String("templateId", templateID.String()), zap.Error(err))
		c.JSON(http.StatusInternalServerError, APIResponse{
			Code:      http.StatusInternalServerError,
			Message:   "Failed to get entities by template: " + err.Error(),
			Timestamp: time.Now(),
		})
		return
	}

	totalPages := int((total + int64(size) - 1) / int64(size))

	c.JSON(http.StatusOK, APIResponse{
		Code:    http.StatusOK,
		Message: "Entities retrieved successfully",
		Data: PaginatedResponse{
			Items:      entities,
			TotalCount: total,
			Page:       page,
			Size:       size,
			TotalPages: totalPages,
		},
		Timestamp: time.Now(),
	})
}
